﻿Imports System.Drawing
Imports System.Windows.Forms
Public Class MessageBox
    Public Shared Function MsgBox(Prompt As Object) As MsgBoxResult
        Return MsgBox(Prompt, New MsgBoxOptions(), MsgBoxStyle.ApplicationModal, Nothing)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Title As Object) As MsgBoxResult
        Return MsgBox(Prompt, Nothing, MsgBoxStyle.ApplicationModal, Title)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Buttons As MsgBoxStyle) As MsgBoxResult
        Return MsgBox(Prompt, New MsgBoxOptions(), Buttons, Nothing)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Options As MsgBoxOptions) As MsgBoxResult
        Return MsgBox(Prompt, Options, MsgBoxStyle.ApplicationModal, Nothing)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Options As MsgBoxOptions, Title As Object) As MsgBoxResult
        Return MsgBox(Prompt, Options, MsgBoxStyle.ApplicationModal, Title)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Title As Object, Options As MsgBoxOptions) As MsgBoxResult
        Return MsgBox(Prompt, Options, MsgBoxStyle.ApplicationModal, Title)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Buttons As MsgBoxStyle, Title As Object) As MsgBoxResult
        Return MsgBox(Prompt, Nothing, Buttons, Title)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Buttons As MsgBoxStyle, Options As MsgBoxOptions) As MsgBoxResult
        Return MsgBox(Prompt, Options, Buttons, Nothing)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Buttons As MsgBoxStyle, Title As Object, Options As MsgBoxOptions) As MsgBoxResult
        Return MsgBox(Prompt, Options, Buttons, Title)
    End Function
    Public Shared Function MsgBox(Prompt As Object, Options As MsgBoxOptions, Buttons As MsgBoxStyle, Title As Object) As MsgBoxResult

#Region "Begin"
        'DefaultButton1, DefaultButton2, DefaultButton3, OkOnly, OkCancel, YesNo, YesNoCancel, Critical, Exclamation, Information, Question, MsgBoxRight, MsgBoxRtlReading
        'AbortRetryIgnore, RetryCancel, ApplicationModal, MsgBoxHelp, MsgBoxRight, MsgBoxRtlReading, MsgBoxSetForeground, SystemModal
        Dim Arrays() As String = Buttons.ToString.Split({", "}, StringSplitOptions.RemoveEmptyEntries)
        Dim Btns As New List(Of Button)
        Options = If(Options, New MsgBoxOptions())
#End Region

#Region "Design MsgBox"

#Region "Text"
        Dim Label1 As New Label
        With Label1
            .SuspendLayout()
            .Text = Prompt
            .AutoSize = True
            .Anchor = AnchorStyles.Left
            .Margin = New Padding(3, 30, 3, 30)
            .ResumeLayout(False)
            .PerformLayout()
        End With
#End Region

#Region "Buttons"
        Dim Button1 As New Button
        With Button1
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Ok
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = (Contains(Arrays, "OkOnly") OrElse Contains(Arrays, "OkCancel") OrElse Contains(Arrays, "ApplicationModal")) AndAlso
                        Not Contains(Arrays, "AbortRetryIgnore") AndAlso Not Contains(Arrays, "RetryCancel") AndAlso Not Contains(Arrays, "YesNo") AndAlso Not Contains(Arrays, "YesNoCancel")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button1)
        End With

        Dim Button2 As New Button
        With Button2
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Yes
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "YesNo") OrElse Contains(Arrays, "YesNoCancel")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button2)
        End With

        Dim Button3 As New Button
        With Button3
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.No
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "YesNo") OrElse Contains(Arrays, "YesNoCancel")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button3)
        End With

        Dim Button4 As New Button
        With Button4
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Abort
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "AbortRetryIgnore")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button4)
        End With

        Dim Button5 As New Button
        With Button5
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Retry
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "RetryCancel") OrElse Contains(Arrays, "AbortRetryIgnore")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button5)
        End With

        Dim Button6 As New Button
        With Button6
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Ignore
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "AbortRetryIgnore")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button6)
        End With

        Dim Button7 As New Button
        With Button7
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Cancel
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "OkCancel") OrElse Contains(Arrays, "YesNoCancel") OrElse Contains(Arrays, "RetryCancel")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button7)
        End With

        Dim Button8 As New Button
        With Button8
            .SuspendLayout()
            .AutoSize = True
            .Text = Options.Help
            .Anchor = AnchorStyles.None
            .UseVisualStyleBackColor = True
            .Margin = New Padding(3, 10, 3, 10)
            .Visible = Contains(Arrays, "MsgBoxHelp")
            .ResumeLayout(False)
            .PerformLayout()

            If .Visible Then Btns.Add(Button8)
        End With
#End Region

#Region "Image"
        Dim PictureBox1 As New PictureBox
        With PictureBox1
            .SuspendLayout()
            CType(PictureBox1, System.ComponentModel.ISupportInitialize).BeginInit()
            .Anchor = AnchorStyles.None
            .Margin = New Padding(0)
            .Size = New System.Drawing.Size(72, 72)
            .SizeMode = PictureBoxSizeMode.AutoSize

            Dim Image As Bitmap = If(Contains(Arrays, "Critical"), SystemIcons.Error.ToBitmap,
                                If(Contains(Arrays, "Exclamation"), SystemIcons.Exclamation.ToBitmap,
                                If(Contains(Arrays, "Information"), SystemIcons.Information.ToBitmap,
                                If(Contains(Arrays, "Question"), SystemIcons.Question.ToBitmap, Nothing))))
            If Image IsNot Nothing AndAlso Options.RightToLeftLayout Then Image.RotateFlip(RotateFlipType.Rotate180FlipY)
            .Image = Image

            .Visible = Contains(Arrays, "Critical") OrElse Contains(Arrays, "Exclamation") OrElse Contains(Arrays, "Information") OrElse Contains(Arrays, "Question")
            CType(PictureBox1, System.ComponentModel.ISupportInitialize).EndInit()
            .ResumeLayout(False)
            .PerformLayout()
        End With
#End Region

#Region "Layout"
        Dim TableLayoutPanel2 As New TableLayoutPanel
        With TableLayoutPanel2
            .SuspendLayout()
            .Anchor = CType(AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right, AnchorStyles)
            .AutoSize = True
            .AutoSizeMode = AutoSizeMode.GrowAndShrink
            .ColumnCount = 4
            .ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 15.0!))
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100.0!))
            .ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 15.0!))
            .Controls.Add(PictureBox1, 1, 0)
            .Controls.Add(Label1, 2, 0)
            .Margin = New Padding(0)
            .RowCount = 1
            .RowStyles.Add(New RowStyle())
            .ResumeLayout(False)
            .PerformLayout()
        End With

        Dim TableLayoutPanel3 As New TableLayoutPanel
        With TableLayoutPanel3
            .SuspendLayout()
            .Anchor = CType(AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right, AnchorStyles)
            .AutoSize = True
            .AutoSizeMode = AutoSizeMode.GrowAndShrink
            .BackColor = Color.FromArgb(240, 240, 240)
            .ColumnCount = 11
            .ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100.0!))
            .ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 30.0!))
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle())
            .ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 15.0!))
            .Controls.Add(Button1, 2, 0)
            .Controls.Add(Button2, 3, 0)
            .Controls.Add(Button3, 4, 0)
            .Controls.Add(Button4, 5, 0)
            .Controls.Add(Button5, 6, 0)
            .Controls.Add(Button6, 7, 0)
            .Controls.Add(Button7, 8, 0)
            .Controls.Add(Button8, 9, 0)
            .Margin = New Padding(0)
            .Font = Options.ButtonFont
            .RowCount = 1
            .RowStyles.Add(New RowStyle(SizeType.Percent, 100.0!))
            .ResumeLayout(False)
            .PerformLayout()
        End With

        Dim TableLayoutPanel1 As New TableLayoutPanel
        With TableLayoutPanel1
            .SuspendLayout()
            .AutoSize = True
            .AutoSizeMode = AutoSizeMode.GrowAndShrink
            '.Dock = DockStyle.Fill
            .MaximumSize = New System.Drawing.Size(840, 768)
            .ColumnCount = 1
            .ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100.0!))
            .Controls.Add(TableLayoutPanel2, 0, 0)
            .Controls.Add(TableLayoutPanel3, 0, 1)
            .RowCount = 2
            .RowStyles.Add(New RowStyle())
            .RowStyles.Add(New RowStyle())
            .Location = New Point(0, 0)
            .Margin = New Padding(0)
            .ResumeLayout(False)
            .PerformLayout()
        End With

        Dim Form As New Form
        With Form
            .SuspendLayout()
            .AutoSize = True
            .AutoScaleMode = AutoScaleMode.None
            .AutoSizeMode = AutoSizeMode.GrowAndShrink
            .BackColor = System.Drawing.Color.White
            .Controls.Add(TableLayoutPanel1)
            .FormBorderStyle = FormBorderStyle.FixedDialog
            .MaximizeBox = False
            .MinimizeBox = False
            .ShowIcon = False
            .ShowInTaskbar = False
            .StartPosition = FormStartPosition.CenterParent
            .Text = Title
            .RightToLeft = Options.RightToLeft
            .RightToLeftLayout = Options.RightToLeftLayout
            .Font = Options.TextFont
            '.ControlBox = (Btns.Count = 1) OrElse Contains(Arrays,"OkCancel") OrElse Contains(Arrays,"YesNoCancel") OrElse Contains(Arrays,"RetryCancel")

            .ResumeLayout(False)
            .PerformLayout()
        End With
#End Region

#Region "Events"
        AddHandler Form.FormClosing, Sub(sender, e) e.Cancel = Btns.Count > 1 AndAlso Form.DialogResult = DialogResult.Cancel AndAlso Not (Contains(Arrays, "OkCancel") OrElse Contains(Arrays, "YesNoCancel") OrElse Contains(Arrays, "RetryCancel"))
        AddHandler Button1.Click, Sub() Form.DialogResult = DialogResult.OK
        AddHandler Button2.Click, Sub() Form.DialogResult = DialogResult.Yes
        AddHandler Button3.Click, Sub() Form.DialogResult = DialogResult.No
        AddHandler Button4.Click, Sub() Form.DialogResult = DialogResult.Abort
        AddHandler Button5.Click, Sub() Form.DialogResult = DialogResult.Retry
        AddHandler Button6.Click, Sub() Form.DialogResult = DialogResult.Ignore
        AddHandler Button7.Click, Sub() Form.DialogResult = DialogResult.Cancel
        AddHandler Button8.Click, Sub() Form.DialogResult = DialogResult.None
#End Region

#Region "Focus"
        If Contains(Arrays, "DefaultButton2") AndAlso Btns.Count > 1 Then
            Form.AcceptButton = Btns(1)
            Btns(1).Focus()
            Btns(1).Select()
        ElseIf Contains(Arrays, "DefaultButton3") AndAlso Btns.Count > 2 Then
            Form.AcceptButton = Btns(2)
            Btns(2).Focus()
            Btns(2).Select()
        ElseIf Btns.Count > 0 Then
            Form.AcceptButton = Btns(0)
            Btns(0).Focus()
            Btns(0).Select()
        End If
#End Region

#End Region

#Region "End"
        If Contains(Arrays, "Critical") Then Beep()
        Select Case Form.ShowDialog
            Case DialogResult.Abort : Return MsgBoxResult.Abort
            Case DialogResult.Cancel : Return If(Btns.Count = 1, MsgBoxResult.Ok, MsgBoxResult.Cancel)
            Case DialogResult.Ignore : Return MsgBoxResult.Ignore
            Case DialogResult.No : Return MsgBoxResult.No
            Case DialogResult.None : Return MsgBoxResult.Cancel
            Case DialogResult.OK : Return MsgBoxResult.Ok
            Case DialogResult.Retry : Return MsgBoxResult.Retry
            Case DialogResult.Yes : Return MsgBoxResult.Yes
            Case Else : Return MsgBoxResult.Cancel
        End Select
#End Region
    End Function

    Private Shared Function Contains(Array() As Object, Key As Object) As Boolean
        For Each item In Array
            If item.Equals(Key) Then Return True
        Next
        Return False
    End Function

    Public Class MsgBoxOptions
        Private _Ok As String = "Ok"
        Private _Yes As String = "Yes"
        Private _No As String = "No"
        Private _Retry As String = "Retry"
        Private _Abort As String = "Abort"
        Private _Ignore As String = "Ignore"
        Private _Cancel As String = "Cancel"
        Private _Help As String = "Help"
        Private _TextFont As Font = SystemFonts.MessageBoxFont
        Private _ButtonFont As Font = SystemFonts.MessageBoxFont
        Private _RightToLeftLayout As Boolean = False
        Private _RightToLeft As RightToLeft = If(Me.RightToLeftLayout, RightToLeft.Yes, RightToLeft.No)

        Public Sub New()
        End Sub

        Public Sub New(RightToLeftLayout As Boolean)
            Me.New(RightToLeftLayout, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, RightToLeft As RightToLeft)
            Me.New(RightToLeftLayout, RightToLeft, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub

        Public Sub New(Font As Font)
            Me.New(Nothing, Nothing, Font, Font, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub
        Public Sub New(TextFont As Font, ButtonFont As Font)
            Me.New(Nothing, Nothing, TextFont, ButtonFont, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub

        Public Sub New(Ok As String, Yes As String, No As String, Abort As String, Retry As String, Ignore As String, Cancel As String, Help As String)
            Me.New(Nothing, Nothing, Nothing, Nothing, Ok, Yes, No, Abort, Retry, Ignore, Cancel, Help)
        End Sub

        Public Sub New(RightToLeftLayout As Boolean, Font As Font)
            Me.New(RightToLeftLayout, Nothing, Font, Font, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, TextFont As Font, ButtonFont As Font)
            Me.New(RightToLeftLayout, Nothing, TextFont, ButtonFont, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, RightToLeft As RightToLeft, TextFont As Font, ButtonFont As Font)
            Me.New(RightToLeftLayout, RightToLeft, TextFont, ButtonFont, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
        End Sub

        Public Sub New(ByVal Options As MsgBoxOptions, Ok As String, Cancel As String)
            Me.New(Options.RightToLeftLayout, Options.RightToLeft, Options.TextFont, Options.ButtonFont, Ok, Options.Yes, Options.No, Options.Abort, Options.Retry, Options.Ignore, Cancel, Options.Help)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, Font As Font, Ok As String, Cancel As String)
            Me.New(RightToLeftLayout, Nothing, Font, Font, Ok, Nothing, Nothing, Nothing, Nothing, Nothing, Cancel, Nothing)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, TextFont As Font, ButtonFont As Font, Ok As String, Cancel As String)
            Me.New(RightToLeftLayout, Nothing, TextFont, ButtonFont, Ok, Nothing, Nothing, Nothing, Nothing, Nothing, Cancel, Nothing)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, RightToLeft As RightToLeft, TextFont As Font, ButtonFont As Font, Ok As String, Cancel As String)
            Me.New(RightToLeftLayout, RightToLeft, TextFont, ButtonFont, Ok, Nothing, Nothing, Nothing, Nothing, Nothing, Cancel, Nothing)
        End Sub

        Public Sub New(RightToLeftLayout As Boolean, Font As Font, Ok As String, Yes As String, No As String, Abort As String, Retry As String, Ignore As String, Cancel As String, Help As String)
            Me.New(RightToLeftLayout, Nothing, Font, Font, Ok, Yes, No, Abort, Retry, Ignore, Cancel, Help)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, TextFont As Font, ButtonFont As Font, Ok As String, Yes As String, No As String, Abort As String, Retry As String, Ignore As String, Cancel As String, Help As String)
            Me.New(RightToLeftLayout, Nothing, TextFont, ButtonFont, Ok, Yes, No, Abort, Retry, Ignore, Cancel, Help)
        End Sub
        Public Sub New(RightToLeftLayout As Boolean, RightToLeft As RightToLeft, TextFont As Font, ButtonFont As Font, Ok As String, Yes As String, No As String, Abort As String, Retry As String, Ignore As String, Cancel As String, Help As String)
            Me.RightToLeftLayout = RightToLeftLayout
            Me.RightToLeft = RightToLeft
            Me.TextFont = TextFont
            Me.ButtonFont = ButtonFont
            Me.Ok = Ok
            Me.Yes = Yes
            Me.No = No
            Me.Abort = Abort
            Me.Retry = Retry
            Me.Ignore = Ignore
            Me.Cancel = Cancel
            Me.Help = Help
        End Sub

        Public Sub SetOkCancel(Ok As String, Cancel As String)
            Me.Ok = Ok
            Me.Cancel = Cancel
        End Sub

        Public Property Ok As String
            Get
                Return _Ok
            End Get
            Set(value As String)
                _Ok = If(value = Nothing, "Ok", value)
            End Set
        End Property
        Public Property Yes As String
            Get
                Return _Yes
            End Get
            Set(value As String)
                _Yes = If(value = Nothing, "Yes", value)
            End Set
        End Property
        Public Property No As String
            Get
                Return _No
            End Get
            Set(value As String)
                _No = If(value = Nothing, "No", value)
            End Set
        End Property
        Public Property Retry As String
            Get
                Return _Retry
            End Get
            Set(value As String)
                _Retry = If(value = Nothing, "Retry", value)
            End Set
        End Property
        Public Property Abort As String
            Get
                Return _Abort
            End Get
            Set(value As String)
                _Abort = If(value = Nothing, "Abort", value)
            End Set
        End Property
        Public Property Ignore As String
            Get
                Return _Ignore
            End Get
            Set(value As String)
                _Ignore = If(value = Nothing, "Ignore", value)
            End Set
        End Property
        Public Property Cancel As String
            Get
                Return _Cancel
            End Get
            Set(value As String)
                _Cancel = If(value = Nothing, "Cancel", value)
            End Set
        End Property
        Public Property Help As String
            Get
                Return _Help
            End Get
            Set(value As String)
                _Help = If(value = Nothing, "Help", value)
            End Set
        End Property
        Public Property TextFont As Font
            Get
                Return _TextFont
            End Get
            Set(value As Font)
                _TextFont = If(value, SystemFonts.MessageBoxFont)
            End Set
        End Property
        Public Property ButtonFont As Font
            Get
                Return _ButtonFont
            End Get
            Set(value As Font)
                _ButtonFont = If(value, Me.TextFont)
            End Set
        End Property
        Public Property RightToLeft As RightToLeft
            Get
                Return _RightToLeft
            End Get
            Set(value As RightToLeft)
                _RightToLeft = If(value = Nothing, If(Me.RightToLeftLayout, RightToLeft.Yes, RightToLeft.No), value)
            End Set
        End Property
        Public Property RightToLeftLayout As Boolean
            Get
                Return _RightToLeftLayout
            End Get
            Set(value As Boolean)
                _RightToLeftLayout = If(value = Nothing, False, value)
            End Set
        End Property

        Public ReadOnly Property Clone() As MsgBoxOptions
            Get
                Return New MsgBoxOptions(Me.RightToLeftLayout, Me.RightToLeft, Me.TextFont, Me.ButtonFont, Me.Ok, Me.Yes, Me.No, Me.Abort, Me.Retry, Me.Ignore, Me.Cancel, Me.Help)
            End Get
        End Property
    End Class
End Class